// 封装axios的请求，返回重新封装的数据格式
import axios from "axios";
import type {
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  Canceler,
} from "axios";
import errorHandle from "./errorHandle";
import { getCookie } from "../cookieUtil";
import config from "@/config";
const CancelToken = axios.CancelToken;

class HttpRequest {
  private baseUrl: string;
  private pending: Record<string, Canceler>;

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl;
    this.pending = {};
  }

  // 获取axios配置
  getInsideConfig() {
    const config = {
      baseURL: this.baseUrl,
      headers: {
        "Content-Type": "application/json;charset=utf-8",
      },
      timeout: 10000,
      withCredentials: true,
    };
    return config;
  }

  removePending(key: string, isRequest = false) {
    if (this.pending[key] && isRequest) {
      this.pending[key]("取消重复请求");
    }
    delete this.pending[key];
  }

  // 设定拦截器
  interceptors(instance: AxiosInstance) {
    // 请求拦截器
    instance.interceptors.request.use(
      (config) => {
        // const params = {
        //   token: getCookie("auth"),
        // };
        // config.params = Object.assign({}, config.params, params);
        const key = config.url + "&" + config.method;
        this.removePending(key, true);
        config.cancelToken = new CancelToken((c) => {
          this.pending[key] = c;
        });
        return config;
      },
      (err) => {
        // debugger
        errorHandle(err);
        // Do something with request error
        return Promise.reject(err);
      }
    );

    // 响应请求的拦截器
    instance.interceptors.response.use(
      (res) => {
        const key = res.config.url + "&" + res.config.method;
        this.removePending(key);
        if (res.status === 200) {
          return Promise.resolve(res.data);
        } else {
          return Promise.reject(res);
        }
      },
      (err) => {
        // Any status codes that falls outside the range of 2xx cause this function to trigger
        // Do something with response error
        // debugger
        errorHandle(err);
        return Promise.reject(err);
      }
    );
  }

  // 创建实例
  request(options: AxiosRequestConfig) {
    const instance = axios.create();
    const newOptions = Object.assign(this.getInsideConfig(), options);
    this.interceptors(instance);
    return instance(newOptions);
  }

  get(
    url: string,
    config?: AxiosRequestConfig
  ): Promise<AxiosResponse> | Promise<any> {
    const options = Object.assign(
      {
        method: "get",
        url: url,
        withCredentials: true,
      },
      config
    );
    return this.request(options);
  }

  // post(url: string, data?: unknown): Promise<AxiosResponse> {
  //   return this.request({
  //     method: "post",
  //     url: url,
  //     data: data,
  //   });
  // }
}

export default HttpRequest;
